#include <stdio.h>


// //模拟实现strlen函数
// //此为计数器方法  还有指针-指针方法 递归的方法
// #include <assert.h>
// size_t my_strlen(const char* str)
// {
//     assert(str);
//     int count = 0;
//     while(*str)
//     {
//         str++;
//         count++;
//     }
//     return count;
// }
// int main()
// {
//     char arr[] = "abcdef";
//     size_t n = my_strlen(arr);
//     printf("%u\n",n);
//     return 0;
// }




// //模拟实现strcpy函数
// #include <assert.h>
// char* my_strcpy(char* dest,const char* src)
// {
//     assert(dest);
//     assert(src);
//     //没有考虑返回类型，需要加上
//     char* start = dest;
//     // while(*src != '\0')
//     // {
//     //     *dest = *src;
//     //     dest++;
//     //     src++;
//     // }
//     // *dest = '\0';
//     //代码简化
//     while(*dest++ = *src++)
//         ;       
//     return start;
// }
// int main()
// {
//     char arr1[] = "abcdef";
//     char arr2[] = { 0 }; 
//     my_strcpy(arr2,arr1);
//     printf("%s\n",arr2);
//     return 0;
// }




// //模拟实现strcat字符串追加函数
// #include <assert.h>
// // char* my_strcpy(char* dest,const char* src)
// // {
// //     assert(dest);
// //     assert(src);
// //     char* start = dest;
// //     while(*dest++ = *src++)
// //         ;       
// //     return start;
// // }
// char* my_strcat(char* dest,const char* src)
// {
//     assert(dest);
//     assert(src);
//     char* ret = dest;
//     while(*dest != '\0')
//     {
//         dest++;
//     }
//     // my_strcpy(dest,src);
//     //调用函数 代码较复杂 不如直接把核心代码写在这
//     while(*dest++ = *src++)
//         ;
//     return ret;
// }
// int main()
// {
//     char arr1[20] = "hello ";
//     char arr2[] = "world";
//     my_strcat(arr1,arr2);
//     printf("%s\n",arr1);
//     return 0;
// }



// //模拟实现strcmp函数
// #include <assert.h>
// int my_strcmp(const char* str1,const char* str2)
// {
//     assert(str1 && str2);
//     while(*str1 == *str2)
//     {
//         if(*str1 == '\0')
//             return 0;
//         str1++;
//         str2++;
//     }
//     return *str1 - *str2;
// }
// int main()
// {
//     char arr1[] = "abcdef";
//     char arr2[] = "abcq";
//     int ret = my_strcmp(arr1,arr2);
//     if(ret > 0)
//     {
//         printf(">\n");
//     }
//     else if(ret == 0)
//     {
//         printf("==\n");
//     }
//     else
//     {
//         printf("<\n");
//     }
//     return 0;
// }




// //模拟实现strncpy 拷贝n个字符 源字符不足n个时继续补0直到为n个
// #include <assert.h>
// #include <string.h>
// char* my_strncpy(char* dest,const char* src,size_t num)
// {
//     assert(dest&&src);
//     //忘记返回指针了
//     char* ret = dest;
//     int i = 0;
//     for(i = 0;i < num;i++)
//     {
//         if(*src == '\0')
//         {
//             *dest = '\0';
//             dest++;
//         }
//         else
//         {
//             *dest = *src;
//             dest++;
//             src++;
//         }
//     }
//     return dest;
// }
// int main()
// {
//     char arr1[20] = "hello world";
//     char arr2[] = "byte";
//     // my_strncpy(arr1,arr2,6);
//     strncpy(arr1,arr2,6);
//     printf("%s\n",arr1);
//     return 0;
// }




// //模拟实现strncat函数
// #include <assert.h>
// char* my_strncat(char* dest,const char* src,size_t num)
// {
//     assert(dest && src);
//     char* ret = dest;
//     while(*dest)
//     {
//         dest++;
//     }
//     while(num--&&*src)
//     {
//         *dest++ = *src++;
//     }
//     *dest = '\0';//追加的字符串最后要加上'\0'
//     return ret;
// }
// int main()
// {
//     char arr1[30] = "To be \0xxxxxxxxxxxxxxxx";
//     char arr2[] = "or not to be";
//     my_strncat(arr1,arr2,20);
//     printf("%s\n",arr1);
//     return 0;
// }




// //模拟实现strstr
// #include <string.h>
// #include <assert.h>
// char* my_strstr(const char* str1,const char* str2)
// {
//     assert(str1 && str2);
//     while(*str1)
//     {
//         if(*str1 == *str2)
//         {
//             char* p1 = str1;
//             char* p2 = str2;
//             int i = 0;
//             while(*p1 == *p2)
//             {
//                 if(*p1 =='\0'&&*p2 == '\0')
//                 return p1-i;
//                 p1++;
//                 p2++;
//                 i++;
//             }
//             //还要考虑p1指针向后走到str1的结尾了，但此时p2还没到str2的结尾
//             //此时就没必要继续再找了，直接结束
//             if(*p1 == '\0')
//                 return NULL;
//             if(*p2 == '\0')
//                 return p1-i;
//         }
//         str1++;
//     }
//     return NULL;
// }
// int main()
// {
//     char arr1[] = "hello this world";
//     char Set[] = "world";
//     char* ret  = strstr(arr1,Set);
//     char* my_ret = my_strstr(arr1,Set);
//     printf("%s\n",ret);
//     printf("%s\n",my_ret);
//     return 0;
// }




// #include <stdio.h>
// #include <string.h>
// int main()
// {
//     char arr[] = "sample@bit.com";
//     const char* sep ="@.";
//     char copy[30] = { 0 };
//     strcpy(copy,arr);
//     char* ret = NULL;
//     //strok内部会保存上一次字符串切割的位置
//     for(ret = strtok(copy,sep);ret != NULL;ret = strtok(NULL,sep) )
//     {
//         printf("%s\n",ret);
//     }
// }




// //strerror
// #include <string.h>
// #include <errno.h>
// int main()
// {
//     // printf("%s\n",strerror(0));
//     // printf("%s\n",strerror(1));
//     // printf("%s\n",strerror(2));
//     // printf("%s\n",strerror(3));
//     // printf("%s\n",strerror(4));
//     FILE* fp = fopen("test.txt","r");//以只读方式打开文件test.txt
//     if(fp == NULL)
//     {
//         printf("error:%s\n",strerror(errno));
//         return 1;
//     }
//     return 0;
// }



// #include <ctype.h>
// int main()
// {
//     // int a = isspace('3');
//     // printf("%d\n",a);
//     // int a = isdigit('a');
//     // printf("%d\n",a);
//     printf("%c\n",tolower('H'));
//     return 0;
// }



// //模拟实现memcpy函数
// #include <string.h>
// #include <assert.h>
// void* my_memcpy(void* dest,void* src,size_t num)
// {
//     assert(dest && src);
//     void* ret = dest;
//     char* p1 = (char*)dest;
//     char* p2 = (char*)src;
//     while(num--)
//     {
//         *p1++ = *p2++;
//     }
//     return ret;
// }
// int main()
// {
//     int arr1[] = {1,2,3,4,5,6};
//     int arr2[10] = {0};
//     memcpy(arr2,arr1,24);
//     float arr3[] = {1.0,2.2,3.4,5.6};
//     float arr4[10] = {0.0};
//     my_memcpy(arr4,arr3,16);
//     return 0;
// }




//模拟实现memmove函数
#include <string.h>
#include <assert.h>
//不建议创建新空间 改成两种复制方式，加判断条件
// void* my_memmove(void* dest,void* src,size_t num)
// {
//     assert(dest && src);
//     char* p1 = (char*)dest;
//     char* p2 = (char*)src;
//     char temp[num];
//     if((p1-p2 > - (signed int) num) && (p1 - p2) < num)
//     {
//         int i = 0;
//         for(i = 0; i < num;i++)
//         {
//             temp[i] = *(p2+i);
//         }
//         p2 = temp;
//     }
//     while(num--)
//     {
//         *p1++ = *p2++;
//     }
// }
void* my_memmove(void* dest,void* src,size_t num)
{
    assert(dest && src);
    char* p1 = (char*)dest;
    char* p2 = (char*)src;
    if(p1- p2 < 0)
    {
        while(num--)
        {
            *p1++ = *p2++;
        }
    }
    else if(p1 - p2 > 0)
    {
        // int i = 0;
        // for(i = 0;i < num;i++)
        // {
        //     *(p1 + num - i - 1) = *(p2 + num - i - 1);
        // }
        //还有更巧妙的写法 nbnb
        //666666666


        while(num--)
        {
            *(p1 + num) = *(p2 + num);
        }

    }
    return dest;
}
int main()
{
    int arr1[] = {1,2,3,4,5,6,7,8,9,10};
    int arr2[] = {1,2,3,4,5,6,7,8,9,10};
    int arr3[] = {1,2,3,4,5,6,7,8,9,10};
    int i = 0;
    //将arr前五个元素向后移动两个单位
    memcpy(arr1+2,arr1,20);
    //正常来说memcpy不具备重叠内存空间之间的数据拷贝
    memmove(arr2+2,arr2,20);
    my_memmove(arr3+2,arr3,20);
    printf("arr1: ");
    for(i = 0;i < 10;i++)
    {
        printf("%d ",arr1[i]);
    }
    printf("\n");
    printf("arr2: ");
    for(i = 0;i < 10;i++)
    {
        printf("%d ",arr2[i]);
    }
    printf("\n");
    printf("arr3: ");
    for(i = 0;i < 10;i++)
    {
        printf("%d ",arr3[i]);
    }
    printf("\n");
    return 0;
}